/**
 * 发布订阅模式(观察者模式)
 * handles: 事件处理函数集合
 * on: 订阅事件
 * emit: 发布事件
 * off: 删除事件
 **/

export default  class DataHub {
    constructor() {
        this.handles = {};
        this.data={}
    }

    // 订阅事件
    on(eventType, handle,data) {
        if (!this.handles.hasOwnProperty(eventType)) {
            this.handles[eventType] = [];
        }
        if (typeof handle == 'function') {
            this.handles[eventType].push(handle);
        } else {
            throw new Error('缺少回调函数');
        }
        if(data){
            let obj=this.data[eventType]
            let copyObj ;
            if(obj){
                copyObj = Object.assign(data, obj);
            }else {
                copyObj=data
            }
            this.data[eventType]=copyObj
            handle(copyObj)
        }
        return this;
    }

    // 发布事件
    emit( ...args) {
        let eventType=args[0]
        if (this.handles.hasOwnProperty(eventType)) {
            this.handles[eventType].forEach((item, key, arr) => {
                item.apply(null, args);
            })
        } else {
            throw new Error(`"${eventType}"事件未注册`);
        }
        return this;
    }

    // 发布事件
    emitRes( ...args) {
        let eventType=args[0]
        if (this.handles.hasOwnProperty(eventType)) {
            this.handles[eventType].forEach((item, key, arr) => {
               return   item.apply(null, args);
            })
        } else {
            throw new Error(`"${eventType}"事件未注册`);
        }
    }
    // 删除事件
    off(eventType, handle) {
        if (!this.handles.hasOwnProperty(eventType)) {
            throw new Error(`"${eventType}"事件未注册`);
        } else if (typeof handle != 'function') {
            throw new Error('缺少回调函数');
        } else {
            this.handles[eventType].forEach((item, key, arr) => {
                if (item == handle) {
                    arr.splice(key, 1);
                }
            })
        }
        return this; // 实现链式操作
    }


    upData(id,data){

        let obj=this.data[id]
        let copyObj ;
        if(obj){
            copyObj = Object.assign(obj, data);
        }else {
            copyObj=data
        }
        this.data[id]=copyObj
    }
}
